/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package model;

import helper.Utilities;
import java.net.Inet4Address;
import java.net.InetSocketAddress;
import java.util.ArrayList;
import main.Peer;

/**
 *
 * @author kuroshaki
 */
public class Response {



    //methods
    public Response(){
        this.failureReason  = "";
        this.warningMessage = "";
        this.interval       = 0;
        this.minInterval    = 0;
        this.complete       = 0;
        this.incomplete     = 0;
        
    }

    public static Response decodeResponse(String response){
        Response result = new Response();
        
        int[] thres = new int[1];
        thres[0] = 0;
        result.failureReason    = getValueFromResponseString(response, FAILURE_REASON, thres);
        result.warningMessage   = getValueFromResponseString(response, WARNING_MESSAGE, thres);
        result.interval         = Integer.parseInt(getValueFromResponseString(response, INTERVAL, thres));
        result.complete         = Integer.parseInt(getValueFromResponseString(response, COMPLETE, thres));
        result.incomplete       = Integer.parseInt(getValueFromResponseString(response, INCOMPLETE, thres));
        result.peers            = new ArrayList<Peer>();
        String[] peers          = getValueFromResponseString(response, PEERS, thres).split(" ");

        for (int i = 0; i < peers.length; ++i){
            Peer peer = new Peer();
            if (peers[i].indexOf(":") == -1) continue;
            String hostAddr = peers[i].substring(0, peers[i].indexOf(":"));
            int port        = Integer.parseInt(peers[i].substring(peers[i].indexOf(":") + 1, peers[i].length()));

            peer.setAddress(new InetSocketAddress(hostAddr, port));
            result.peers.add(peer);
        }
       
        return result;
    }

    private static String getValueFromResponseString(String response, String key, int[] thresObj){
        StringBuilder sb = new StringBuilder();
        int thres = thresObj[0];
        thres = response.indexOf(key, thres);

        for (thres = thres + key.length(); response.charAt(thres) != '\n'; ++thres) {
            sb.append(response.charAt(thres));
        }

        thresObj[0] = thres;

        return sb.toString();
    }

    public String encodeResponse(){
        StringBuilder res = new StringBuilder();

        res.append(FAILURE_REASON);
        res.append(this.failureReason);
        res.append("\n");

        res.append(WARNING_MESSAGE);
        res.append(this.warningMessage);
        res.append("\n");

        res.append(INTERVAL);
        res.append(this.interval);
        res.append("\n");

        res.append(COMPLETE);
        res.append(this.complete);
        res.append("\n");

        res.append(INCOMPLETE);
        res.append(this.incomplete);
        res.append("\n");

        res.append(PEERS);
        for (int i = 0; i < 50 && i < this.peers.size(); ++i){
            Peer peer = this.peers.get(i);

            res.append(peer.getAddress().getAddress().getHostAddress());
            res.append(":");
            res.append(peer.getAddress().getPort());
            res.append(" ");
        }
        res.append("\n");

        return res.toString();
    }

    //methods set
    public void setFailureReason(String st){
        this.failureReason = st;
    }

    public void setWarningMessage(String st){
        this.warningMessage = st;
    }

    public void setInterval(int in){
        this.interval = in;
    }

    public void setMinInterval(int in){
        this.minInterval = in;
    }

    public void setComplete(int in){
        this.complete = in;
    }

    public void setIncomplete(int in){
        this.incomplete = in;
    }

    public void setPeers(ArrayList<Peer> p){
        this.peers = p;
    }

    //methods get
    public String getFailureReason(){
        return this.failureReason;
    }

    public String getWarningMessage(){
        return this.warningMessage;
    }

    public int getInterval(){
        return this.interval;
    }

    public int getMinInterval(){
        return this.minInterval;
    }

    public int getComplete(){
        return this.complete;
    }

    public int getIncomplete(){
        return this.incomplete;
    }

    public ArrayList<Peer> getPeers(){
        return this.peers;
    }

    //atribut
    private String failureReason;       //string dari pesan error, key lain tidak perlu ada jika terjadi error
    private String warningMessage;      //hanya peringatan, key lain tetap diproses
    private int interval;               //detik interval harus mengirimkan request lagi ke tracker
    private int minInterval;            //optional
    //private String trackerId;         //string yang dikembalikan untuk request selanjutnya (tidak perlu)
    private int complete;               //banyaknya client yang memiliki file utuh (seeders)
    private int incomplete;             //banyaknya client non-seeder
    private ArrayList<Peer> peers;   //list dari ip dan port peer, default sebanyak 50

    public static final String FAILURE_REASON   = "failure_reason ";
    public static final String WARNING_MESSAGE  = "warning_message ";
    public static final String INTERVAL         = "interval ";
    public static final String COMPLETE         = "complete ";
    public static final String INCOMPLETE       = "incomplete ";
    public static final String PEERS            = "peers ";
}
